package tables

import (
	"encoding/json"
	"fmt"
	"mini-admin/internal/open"
	v1 "mini-admin/internal/open/service/v1"
	types1 "mini-admin/internal/types"
	"strconv"

	// "github.com/Cluas/go-wechat/wechat"
	wechat "gitee.com/quantum-force/wxopen-api"
	"github.com/GoAdminGroup/go-admin/context"
	"github.com/GoAdminGroup/go-admin/modules/db"
	"github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
	"github.com/GoAdminGroup/go-admin/template/icon"
	"github.com/GoAdminGroup/go-admin/template/types/action"
	"github.com/GoAdminGroup/go-admin/template/types/form"
	"gorm.io/gorm"

	"mini-admin/internal/conf"
	"mini-admin/internal/database"
	"mini-admin/internal/model"
)

// GetWechatTemplate return the model of table system_templates.
func GetWechatTemplate(ctx *context.Context) (stTable table.Table) {

	stTable = table.NewDefaultTable(table.DefaultConfigWithDriver("postgresql"))

	info := stTable.GetInfo()
	info.AddField("ID", "id", db.Int).FieldSortable()
	info.AddField("模版ID", "template_id", db.Int)
	info.AddField("版本号", "user_version", db.Varchar)
	info.AddField("版本描述", "user_desc", db.Varchar)
	info.AddButton("同步微信模版库", icon.Adjust, action.Ajax("sync_wechat_template",
		func(ctx *context.Context) (success bool, msg string, data interface{}) {
			client := wechat.NewClient(nil)
			openClient := open.New(conf.Conf.OpenAddress)
			resp, err := openClient.ComponentAccessToken(ctx.Request.Context(), &v1.ComponentAccessTokenRequest{
				Platform: v1.Platform_PLATFORM_WECHAT,
				AppId:    conf.Conf.WechatAppID,
			})
			if err != nil {
				return false, fmt.Sprintf("openClient.ComponentAccessToken err:%s", err.Error()), nil
			}
			templateList, _, err := client.WXA.GetTemplateList(ctx.Request.Context(), resp.ComponentAccessToken)
			if err != nil {
				return false, fmt.Sprintf("client.WXA.GetTemplateList err:%s", err.Error()), nil
			}
			conn := database.New(conf.Conf.ORM)
			var templates []*model.WechatTemplate
			conn.Model(&model.WechatTemplate{}).Find(&templates)
			ids := make(map[int]int)
			for _, t := range templates {
				ids[t.TemplateID] = 1
			}
			err = conn.Transaction(func(tx *gorm.DB) error {
				for _, t := range templateList.TemplateList {
					templateID, _ := strconv.Atoi(string(t.TemplateID))
					if _, ok := ids[templateID]; !ok {
						newTemplate := model.WechatTemplate{
							TemplateID:  templateID,
							UserVersion: t.UserVersion,
							UserDesc:    t.UserDesc,
						}
						tx.Save(&newTemplate)
					}
				}
				return nil
			})
			if err != nil {
				return false, fmt.Sprintf("txerr:%s", err.Error()), nil
			}
			return true, "ok", nil

		}))
	info.AddButton("一键升级到最新版本", icon.Upload, action.Ajax("upgrade_wechat_template",
		func(ctx *context.Context) (success bool, msg string, data interface{}) {

			conn := database.New(conf.Conf.ORM)
			template := new(model.WechatTemplate)
			if err := conn.Order("created_at desc").First(&template).Limit(1).Error; err != nil {
				return false, "", nil
			}
			var appVersions []*model.MiniAppVersion
			if err := conn.Model(&model.MiniAppVersion{}).
				Where("status = ? and platform = ? and release_version != ?",
					"released", types1.Wechat,
					template.UserVersion).Find(&appVersions).Error; err != nil {
				return false, "", nil
			}
			appIDs := make([]string, len(appVersions))
			for i, app := range appVersions {
				appIDs[i] = app.AppID
			}
			var brandMiniApps []*model.BrandMiniApp
			if err := conn.Model(&model.BrandMiniApp{}).
				Where("app_id in ? and platform = ?",
					appIDs, types1.Wechat,
					template.UserVersion).Find(&brandMiniApps).Error; err != nil {
				return false, "", nil
			}
			brandMap := make(map[string]int64, len(brandMiniApps))
			for _, a := range brandMiniApps {
				brandMap[a.AppID] = a.BrandID
			}
			err := conn.Transaction(func(tx *gorm.DB) error {
				for _, appVersion := range appVersions {
					appVersion.Status = "auditing"
					appVersion.Stage = "initialized"
					ext := fmt.Sprintf(
						`{"brand_id": %d}`,
						brandMap[appVersion.AppID])

					jobData, err := json.Marshal(template.ToVO(fmt.Sprintf(`{"extAppid": "%s", "ext": %s}`, appVersion.AppID, ext)))
					if err != nil {
						return err
					}
					appVersion.AuditVersion = template.UserVersion
					schedule := model.Schedule{
						RefID:     appVersion.ID,
						JobType:   "commit_code",
						JobData:   jobData,
						JobStatus: 0,
					}
					err = conn.Create(&schedule).Error
					if err != nil {
						return err
					}
					err = conn.Save(&appVersion).Error
					if err != nil {
						return err
					}
					// TODO: send nsq message
				}
				return nil
			})
			if err != nil {
				return false, "", nil
			}
			return true, "ok", nil

		}))

	info.SetTable("wechat_template").SetTitle("微信小程序模版").SetDescription("微信小程序代码模版")

	formList := stTable.GetForm()
	formList.AddField("ID", "id", db.Int, form.Default).FieldDisplayButCanNotEditWhenUpdate().FieldDisableWhenCreate()
	formList.AddField("模版ID", "template_id", db.Int, form.Number)
	formList.AddField("版本号", "user_version", db.Varchar, form.Text)
	formList.AddField("版本描述", "user_desc", db.Varchar, form.Text)

	formList.SetTable("wechat_template").SetTitle("微信小程序模版").SetDescription("微信小程序代码模版")

	return
}
